// Copyright (C) 2022-2022 wuchengwen. All Rights Reserved.
// Description:
// Author : wuchengwen <wuchw@foxmail.com>
// Date :2022-08-29

#include <iomanip>
#include <iostream>
#include <random>

using namespace std;
// https://en.cppreference.com/w/cpp/language/attributes/likely
unsigned int Total(unsigned int num, unsigned int &res)
{
    if (num == 1) {
        return 1;
    }
    res += num;
    return Total(num - 1, res);
}

unsigned int TotalLikely(unsigned int num, unsigned int &res)
{
    if (num == 1) [[unlikely]] {
        return 1;
    }
    res += num;
    return TotalLikely(num - 1, res);
}

unsigned int GenRandom() noexcept
{
    static std::random_device rd;
    static std::mt19937 gen(rd());
    static std::normal_distribution<> dis(1000, 10);
    return (unsigned int)dis(gen);
}

int main()
{
    auto benchmark = [](auto fun, auto rem) {
        const auto start = std::chrono::high_resolution_clock::now();
        auto res = 1U;
        for (auto size {1ULL}; size != 10'000'00ULL; ++size) {
            fun(GenRandom(), res);
            res = 0;
        }
        const std::chrono::duration<double> diff = std::chrono::high_resolution_clock::now() - start;
        std::cout << "Time: " << std::fixed << std::setprecision(6) << diff.count() << " sec " << rem << std::endl;
        cout << res << endl;
    };

    benchmark(Total, "no likely");
    benchmark(TotalLikely, "likely");
}